/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.diagram.deployment.editpart;

import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.requests.CreateConnectionRequest;
import org.eclipse.gef.requests.ReconnectRequest;

import com.cea.papyrus.core.commands.connection.ConnectionCreateCommand;
import com.cea.papyrus.core.commands.connection.ConnectionReconnectCommand;
import com.cea.papyrus.core.helper.ModelerHelper;
import com.cea.papyrus.core.pseudoelement.EnhancedType;
import com.cea.papyrus.core.pseudoelement.UMLElementFactory;
import com.cea.papyrus.diagram.deployment.command.ConnectionCreateCommandFactory;
import com.cea.papyrus.diagram.deployment.command.ConnectionReconnectCommandFactory;
import com.cea.papyrus.diagraminterchange2.di2.GraphEdge;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;


/**
 * Policy for connection creation.
 * Redefines the common policy for association creation in this diagram.
 */
public class GraphNodeEditPolicy extends com.cea.papyrus.core.editpart.GraphNodeEditPolicy {

	/* 
	 * Start creation of a connection. The Command is created, and the src is set.
	 */
	/**
	 * 
	 * 
	 * @param request 
	 * 
	 * @return 
	 */
	@Override
	protected Command getConnectionCreateCommand(CreateConnectionRequest request) {

		Class type;
		Object newObjectDescription 
		= EnhancedType.getNewObjectDescription(request);
							
		if (!(getHost().getModel() instanceof GraphNode)) {
			return null;
		}

		GraphNode source        = (GraphNode) getHost().getModel();
		GraphElement container  = source.getContainer();

		// Test creation restriction in Connector creation
		// (due to filters defined in PaletteMenu extension
		boolean noRestriction = true;
		if (newObjectDescription instanceof UMLElementFactory) {
			UMLElementFactory enhancedType = (UMLElementFactory) newObjectDescription;
			type          = enhancedType.getClazz();
			noRestriction = enhancedType.canExecute(source);
		} else {
			type = (Class)  newObjectDescription;
		}

		/*if((!(container instanceof Diagram))
				&&	(container.getSemanticModel() == null)) {
			// the source dont have to be a property for instance.
			return null; 
		}*/

		Point location = computeAnchorLocation(request.getLocation(), getHost());
		if(source.getSemanticModel()!=null ){
			if(ModelerHelper.getFactory().canConnect(type, ((Uml1SemanticModelBridge)source.getSemanticModel()).getElement(), null)&& noRestriction) {
				ConnectionCreateCommand cmd = ConnectionCreateCommandFactory.eINSTANCE.getConnectionCreateCommand(source, newObjectDescription, location);
				request.setStartCommand(cmd);
				return cmd;
			}
		}
		return null;
	}

	/* 
	 * Returns the <code>Command</code> to reconnect a connection's <i>source</i> end to the
	 * host.
	 */
	/**
	 * 
	 * 
	 * @param request 
	 * 
	 * @return 
	 */
	@Override
	protected Command getReconnectSourceCommand(ReconnectRequest request) {
		if (!(getHost().getModel() instanceof GraphNode)) {
			return null;
		}

		GraphEdge connector = (GraphEdge) request.getConnectionEditPart().getModel();
		GraphNode newSource = (GraphNode) getHost().getModel();

		Point location = computeAnchorLocation(request.getLocation(), getHost());
		ConnectionReconnectCommand cmd = ConnectionReconnectCommandFactory.eINSTANCE.getConnectionReconnectCommand(connector, newSource, location, ConnectionReconnectCommand.SOURCE); 
		return cmd;
	}

	/* 
	 * Returns the <code>Command</code> to reconnect a connection's <i>target</i> end to the
	 * host.
	 */
	/**
	 * 
	 * 
	 * @param request 
	 * 
	 * @return 
	 */
	@Override
	protected Command getReconnectTargetCommand(ReconnectRequest request) {
		if (!(getHost().getModel() instanceof GraphNode)) {
			return null;
		}

		GraphEdge connector = (GraphEdge) request.getConnectionEditPart().getModel();
		GraphNode newTarget = (GraphNode) getHost().getModel();

		Point location = computeAnchorLocation(request.getLocation(), getHost());
		ConnectionReconnectCommand cmd = ConnectionReconnectCommandFactory.eINSTANCE.getConnectionReconnectCommand(connector, newTarget, location, ConnectionReconnectCommand.TARGET); 

		return cmd;
	}
}


